home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
winsock
/
ircii2-6.zip
/
SRC\IRCII-2.6\SOURCE\SCANDIR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-29
|
7KB
|
264 lines
#ifndef lint
static char rcsid[] = "@(#)$Id: scandir.c,v 1.24 1994/10/08 16:50:35 mrg Stab $";
#endif
#include "defs.h"
#ifndef HAVE_SCANDIR
#if (!defined(ultrix) && !defined(__386BSD__) && !defined(_HPUX_SOURCE)) || defined(HPUX7)
/*
* Copyright (c) 1983 Regents of the University of California. All rights
* reserved.
*
* Redistribution and use in source and binary forms are permitted provided that
* the above copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and other
* materials related to such distribution and use acknowledge that the
* software was developed by the University of California, Berkeley. The
* name of the University may not be used to endorse or promote products
* derived from this software without specific prior written permission. THIS
* SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
# if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)scandir.c 5.3 (Berkeley) 6/18/88";
# endif /* LIBC_SCCS and not lint */
# define NULL 0
/*
* Scan the directory dirname calling select to make a list of selected
* directory entries then sort using qsort and compare routine dcomp. Returns
* the number of entries and a pointer to a list of pointers to struct direct
* (through namelist). Returns -1 if there were any errors.
*/
/*
* Mike Sandrof added this for HPUX compatibility in
* IRCII on the advice of some HPUX users - 5/11/90
* this is no longer valid, as hpux has its own scandir(), june 1993, phone.
* at least, for some versions of hpux.. oct 1994, mrg.
*
* Brett Sivies added POSIX here.
*/
# if defined(XD88) || defined(__svr4__) || defined(POSIX) || defined(__linux__) \
|| defined(SVR3) || defined(__osf__) || defined(M_UNIX) || defined(_SEQUENT_) \
|| defined(__QNX__) || defined(__BORLANDC__)
/*
** SCANDIR
** Scan a directory, collecting all (selected) items into a an array.
*/
# ifndef __BORLANDC__
# include <stdio.h>
# include <sys/types.h>
# include <dirent.h>
# include <sys/file.h>
# ifdef XD88
# include <sys/unistd.h>
# else
# include <unistd.h>
# endif /* XD88 */
# else
# include "irc.h"
# include <dirent.h>
# endif
/* Initial guess at directory size. */
# define INITIAL_SIZE 30
# ifndef DIRSIZ
# define DIRSIZ(d) (sizeof(struct dirent) + strlen(d->d_name) + 1)
# endif
/* Linked in later. */
extern char *new_malloc();
extern char *new_realloc();
extern char *strcpy();
int
scandir(Name, List, Selector, Sorter)
#if defined(__linux__) || defined(__sgi)
const char *Name;
#else
char *Name;
#endif
struct dirent ***List;
int (*Selector)();
int (*Sorter)();
{
struct dirent **names;
static struct dirent *E;
register DIR *Dp;
register int i;
register int size = INITIAL_SIZE;
if (!(names = (struct dirent **) new_malloc(size * sizeof names[0])) || access(Name, R_OK | X_OK) || !(Dp = opendir(Name)))
return(-1);
/* Read entries in the directory. */
for (i = 0; (E = readdir(Dp)); )
if (Selector == NULL || (*Selector)(E))
{
/* User wants them all, or he wants this one. */
if (++i >= size)
{
size <<= 1;
names = (struct dirent **) new_realloc((char *)names, size * sizeof names[0]);
if (names == NULL)
{
closedir(Dp);
new_free(&names);
return(-1);
}
}
/* Copy the entry. */
if ((names[i - 1] = (struct dirent *) new_malloc(DIRSIZ(E))) == NULL)
{
closedir(Dp);
new_free(&names);
return(-1);
}
#if !defined(__QNX__) && !defined(__BORLANDC__)
names[i - 1]->d_ino = E->d_ino;
names[i - 1]->d_reclen = E->d_reclen;
#endif
(void) strcpy(names[i - 1]->d_name, E->d_name);
}
/* Close things off. */
names = (struct dirent **) new_realloc((char *) names, (i + 1) * sizeof names[0]);
names[i] = 0;
*List = names;
closedir(Dp);
/* Sort? */
if (i && Sorter)
qsort((char *)names, i, sizeof names[0], Sorter);
return(i);
}
#else
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/file.h>
# include "irc.h"
# if defined(ISC22) || defined(ESIX) || defined(HPUX7)
# ifdef ESIX
# include <dirent.h>
# else
# include <sys/dirent.h>
# endif /* ESIX */
# undef DIRSIZ
# if defined(ISC22) || defined(ESIX)
# define DIRSIZ(dp) \
(( sizeof( struct dirent) + (strlen(dp->d_name)+1) ))
# else
# define DIRSIZ(dp) \
((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1+3)&~ 3))
# endif /* defined(ISC22) || defined(ESIX) */
# define direct dirent
# else
# include <sys/dir.h>
# endif /* defined(ISC22) || defined(ESIX) */
/* End of Mike Sandrof's change */
int scandir(dirname, namelist, select, dcomp)
#ifdef NeXT
const char *dirname;
#else
char *dirname;
#endif /* NeXT */
struct direct *(*namelist[]);
int (*select) (), (*dcomp) ();
{
register struct direct *d,
*p,
**names;
register int nitems;
register char *cp1,
*cp2;
struct stat stb;
long arraysz;
DIR *dirp;
if (access(dirname, R_OK|X_OK))
return (-1);
if ((dirp = opendir(dirname)) == NULL)
return (-1);
if (fstat(dirp->dd_fd, &stb) < 0)
return (-1);
/*
* estimate the array size by taking the size of the directory file and
* dividing it by a multiple of the minimum size entry.
*/
arraysz = (stb.st_size / 24);
names = (struct direct **) new_malloc(arraysz * sizeof(struct direct *));
if (names == NULL)
return (-1);
nitems = 0;
while ((d = readdir(dirp)) != NULL)
{
if (select != NULL && !(*select) (d))
continue; /* just selected names */
/*
* Make a minimum size copy of the data
*/
p = (struct direct *) new_malloc(DIRSIZ(d));
if (p == NULL)
return (-1);
#if !defined(__BORLANDC__)
p->d_ino = d->d_ino;
p->d_reclen = d->d_reclen;
#endif
# if ! defined(ISC22) && ! defined(ESIX)
p->d_namlen = d->d_namlen;
# endif /* ! defined(ISC22) && ! defined(ESIX) */
for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++;);
/*
* Check to make sure the array has space left and realloc the
* maximum size.
*/
if (++nitems >= arraysz)
{
if (fstat(dirp->dd_fd, &stb) < 0)
return (-1); /* just might have grown */
arraysz = stb.st_size / 12;
names = (struct direct **) new_realloc((char *) names,
arraysz * sizeof(struct direct *));
if (names == NULL)
return (-1);
}
names[nitems - 1] = p;
}
closedir(dirp);
if (nitems && dcomp != NULL)
qsort(names, nitems, sizeof(struct direct *), dcomp);
*namelist = names;
return (nitems);
}
/*
* Alphabetic order comparison routine for those who want it.
*/
int alphasort(d1, d2)
struct direct **d1,
**d2;
{
return (strcmp((*d1)->d_name, (*d2)->d_name));
}
#endif
#endif /* ultrix || __386BSD__ || BSD */
#endif /* !HAVE_SCANDIR */